<template>
	<div class="page-wrapper">
		<div style="height:100%; background:#fff; padding-top:calc( 2 * var(--mPadding));">
			<div class="box-container" v-if="isEditing">
				<div class="flex-btn opacity" @click="handleSelect('all')">全选</div>
				<div class="flex-btn opacity" @click="handleSelect('single')">单休</div>
				<div class="flex-btn opacity" @click="handleSelect('double')">双休</div>
				<div class="flex-btn opacity" @click="handleSelect('clear', true)">清空</div>
				<div class="flex-btn gray" style="margin-left:auto;" @click="handleClear">取消</div>
				<div class="flex-btn" @click="handleSave" >
					<i class="ri-save-line"></i>
					保存
				</div>
			</div>
			<div class="box-container" v-else>
				<div class="flex-btn large" @click="isEditing = true">
					<img :src="Icon" />
					<span>设置巡检工作日历</span>
				</div>
			</div>
			
			<div class="toggle-container">
				<div class="flex-btn white small" @click="changeMonth(-1)"><i class="ri-arrow-left-s-line"></i></div>
				<ValidatorDatePicker :data="{ paramKey:'date', type:'month',  validator:dateValidator, clearable:false }" :form="form" />
				<div class="flex-btn white small" @click="changeMonth(1)"><i class="ri-arrow-right-s-line"></i></div>
			</div>
			
			<div class="calendar-container">
				<div class="calendar-header">
					<div>周一</div>
					<div>周二</div>
					<div>周三</div>
					<div>周四</div>
					<div>周五</div>
					<div>周六</div>
					<div>周日</div>
				</div>
				<div class="calendar-body">
					<div class="item-wrapper"
						v-for="item in daylist" :key="item.timestamp" @click="clickevent(item)"
					>
						<div 
							class="item"
							:class="{ inMonth:item.month === month, selected:hasSetDates[item.date] }"
						>
							<span>{{ item.day }}</span>
						</div>
					</div>
				</div>
			</div>
			<div style="width:50%; margin:0 auto; padding:var(--baseFontSize); color:rgba(0, 0, 0, 0.65);">
				<i class="ri-information-fill" style="margin-right:var(--sPadding)"></i>
				<span>巡检工作日历，非工作日不生成巡检任务</span>
			</div>
		</div>
		<!-- 跳转确认 -->
		
	</div>

</template>

<script setup>
	import { ref, watch, reactive, onMounted } from 'vue'
	import { getWorkdayList, addWorkdayList } from '@/api/cycle.js';
	import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
	import ValidatorDatePicker from '@/components/ValidatorDatePicker.vue';
	import { ElMessage, ElMessageBox, ElPopconfirm, ElInput  } from 'element-plus'
	import Icon from '@/assets/icon-period.png';
	const isEditing = ref(false);
	// 需要展示的所有日期列表
	const daylist = ref([])
	// 年月日数据暂存
	const date = new Date();
	const year = ref(date.getFullYear());
	const month = ref(date.getMonth() + 1);
	const day = ref(date.getDate());
	const form = reactive({ date });
	const hasSetDates = ref({});
	let prevSetDates = {}; 

	// 清空选中状态
	function handleClear(){
		// 重置回接口初始的状态
		isEditing.value = false;
	}
	function handleSave(resolve, reject){	
		let arr = [];
		Object.keys(hasSetDates.value).forEach(key=>{
			if ( hasSetDates.value[key] ) {
				arr.push(key);
			}
		})
		addWorkdayList( arr )
		.then(res=>{
			if ( res.data.code === 200 ){
				ElMessage({
					type:'success',
					message:'设置巡检工作日历成功'
				});
				// 重置prevSetDates
				prevSetDates = arr.reduce((sum, cur)=>{
					sum[cur] = true;
					return sum;
				}, {});
				
				if ( resolve && typeof resolve === 'function' ) resolve();
			}
		})
		
	}
	function compareIsEqual(){
		let result = true;
		let obj = {};
		Object.keys(hasSetDates.value).forEach(key=>{
			if ( hasSetDates.value[key] ) {
				obj[key] = hasSetDates.value[key];
			}
		})
		let prevKeys = Object.keys(prevSetDates);
		let curKeys = Object.keys(obj);
		
		if ( prevKeys.length !== curKeys.length ) result = false;
		for( let i = 0; i < curKeys.length; i++ ){
			let key = curKeys[i];
			if ( hasSetDates.value[key] !== prevSetDates[key] ) {
				result = false;
				break;
			}  
		}
		
		return result;
	}
	function checkIsChange(){
		// 判断当前月的巡检日是否有变动
		return isEditing.value && !compareIsEqual();
	}
	function openModal(date){
		ElMessageBox.alert('要保存当前月的巡检工作日设置吗？', '确认操作', {
			confirmButtonText:'保存',
			showCancelButton:true,
			cancelButtonText:'取消',
			callback:(action)=>{
				if ( action === 'confirm') {
					new Promise((resolve, reject)=>{
						handleSave(resolve, reject)
					})
					.then(()=>{
						// 先自动保存，再更新要切换的月份
						form.date = date;
					})
				} else if ( action === 'cancel'){
					
				}
			}
		})
	}
	function dateValidator(date){
		console.log('date...', date);
		let res = checkIsChange();
		if ( res ) {
			openModal(date);
		}
		return res;
	}
	// 初始化日期列表
	const checkChangeDate = (date)=>{
		if ( checkIsChange() ) {
			// 如果当前月有设置的日期对象，则显示是否确定要保存;
			openModal(date);
		} else {
			form.date = date;
		}
	}
	watch(()=>form.date, ( prevDate, nextDate )=>{
		year.value = form.date.getFullYear();
		month.value = form.date.getMonth() + 1;
		day.value = form.date.getDate();
		getWorkdayList({ year:year.value, month:month.value })
		.then(res=>{
			if ( res.data.code === 200 ) {
				let obj = {};
				res.data.data.forEach(item=>{
					obj[item.workDay] = true;
				})
				hasSetDates.value = obj;
				prevSetDates = { ...obj };
			}
		})	
		// 重新计算新的日期列表
		getDaylist();
	}, { immediate:true });
	
	// 计算需要展示的第一个日期
	function startandendday() {
		// 复制日期对象,setDate()会直接影响原对象
		const cloneNowDate = new Date(form.date);
		// 先获取这个月的第一天
		const firstdaytime = cloneNowDate.setDate(1);
		// 获取第一天是周几
		let firstdayweek = new Date(firstdaytime).getDay()
		if (firstdayweek === 0) {
			firstdayweek = 7;
		}
		// 展示时间的第一天
		return firstdaytime - (firstdayweek - 1) * 24 * 60 * 60 * 1000
	}
	// 向列表填充数据
	function getDaylist() {
		const starttime = startandendday();
		const arr = [];
		// 获取当前月的最后一天 
		const endDateTime = new Date(year.value, month.value, 0);
		for (let i = 0; i <= 60; i++) {
			const obj = {}
			const timestamp = starttime + i * 24 * 60 * 60 * 1000
			const date = new Date(timestamp)
			const year1 = date.getFullYear();
			let temp1 = date.getMonth();
			let month1 = date.getMonth() + 1;
			let monthStr = month1 < 10 ? '0' + month1 : month1;
			let day1 = date.getDate();
			let dayStr = day1 < 10 ? '0' + day1 : day1;
			const week = date.getDay();
			if ( timestamp > endDateTime ) {
				// i >= 41 确保每个月的日历都是6行
				if ( week === 1 && i >= 41 ) { break }
			}
			obj["timestamp"] = timestamp
			obj["year"] = year1
			obj["month"] = month1
			obj["day"] = day1
			obj["week"] = week
			obj["date"] = year1 + '-' + monthStr + '-' + dayStr;
			arr.push(obj);
		}
		daylist.value = arr;
	}

	// 日期点击事件
	const clickevent = (item) => {
		if (item.month !== month.value ) {
			// 如不在当前月，先跳转至选中的月份
			checkChangeDate(new Date(item.date));
		} else {
			// 如在当前月的
			if ( isEditing.value ) {
				if ( !hasSetDates.value[item.date] ) {
					hasSetDates.value[item.date] = true;
				} else {
					hasSetDates.value[item.date] = !hasSetDates.value[item.date];
				}
			}
		}
	}
	
	// 点击上个月或者下个月
	const changeMonth = (num) => {
		let newMonth = month.value + num;
		// 如果大于12，转到下一年
		if (newMonth > 12) {
			year.value += 1;
			newMonth = 1;
		}
		if (newMonth < 1) {
			year.value -= 1;
			newMonth = 12;
		}
		checkChangeDate(new Date(`${year.value}-${newMonth}-${day.value}`));
	}
	// 处理选择类型
	const handleSelect = (type, isDel) => {
		// 获取当前月份的所有日期
		let currentDates = [];		
		const monthDates = daylist.value.filter(i=>i.month === month.value).map(i=>i.date);
		// 根据类型筛选日期
		switch (type) {
			case 'all':// 全选当月所有日期
			case 'clear': // 清空当月的巡检日期
				currentDates = monthDates;
				break;
			case 'single': // 单休：排除周日（周日为0）
				currentDates = daylist.value
				.filter(item=> item.month === month.value && item.week !== 0)
				.map(i=>i.date)
				break;
			case 'double': // 双休：排除周六（6）和周日（0）
				currentDates = daylist.value
					.filter((item) =>
						item.month === month.value && item.week !== 6 && item.week !== 0
					).map(i=>i.date);
				break;
		}
		const obj = { ...hasSetDates.value };
		monthDates.forEach(item=>{
			if ( isDel ) {
				obj[item] = false;
				return;
			}
			if ( currentDates.includes(item)) {
				obj[item] = true;
			} else {
				obj[item] = false;
			}
		})
		hasSetDates.value = obj;
	}
</script>

<style lang="scss">	
	.box-container {
		width:50%;
		margin:0 auto;
		height:8vh;
		display:flex;
		align-items: center;
	}
	.toggle-container {
		width:50%;
		margin:0 auto;
		height:5.54vh;
		margin-bottom:var(--mPadding);
		background:#f5f7fa;
		display:flex;
		justify-content: space-between;
		align-items: center;
		padding:0 var(--mPadding);
	}
	.calendar-container {
		width:50%;
		margin:0 auto;
		
		.calendar-header {
			display:flex;
			width:100%;
			height:5.54vh;
			line-height:5.54vh;
			background:#f5f7fa;
			font-size:var(--baseFontSize);
			div {
				width:14.28%;
				text-align:center;
			}
		}
		.calendar-body {
			display:flex;
			flex-wrap:wrap;
			font-size:var(--24FontSize);
			.item-wrapper {
				width:14.28%;
				padding:0 var(--baseFontSize);
				padding-top:var(--lPadding);
				.item {
					padding:var(--sPadding);
					border:1px solid #E1E4EA;
					height:7.16vh;
					color:#CACFD8;
					border-radius:var(--sPadding);
					cursor:pointer;
				}
				.item.inMonth {
					background-color:#f5f7fa;
					color:#99a0ae;
				}
				.item.selected {
					background-color:#C0D5FF;
					border-color:#335CFF;
					color:#335CFF;
				}
			}
			
		}
	}
</style>